RDD - Action Aggregate
The aggregate() action is an advanced reduction operation. While standard reduce() requires the final output type to be identical to the RDD's element type, aggregate() allows you to return a completely different data type.
It is highly used for calculating compound metricslike calculating averages (which requires tracking both a sum total and a record count at the same time).
Syntax and Key Arguments
rdd.aggregate(zeroValue, seqOp, combOp)
zeroValue: The initial identity value used for the accumulation in each partition and in the final merge (e.g.(0, 0)for sum and count).seqOp(Sequence Operator): A function applied locally within each partition to accumulate row values into the zeroValue.combOp(Combiner Operator): A function used to merge the accumulated values from different partitions together at the Driver node.
PySpark Code Example: Calculating Average
Let's calculate the average of a list of numbers. The elements are integers, but we want to return a tuple (sum, count) so we can divide them at the end.
Setup Spark Session
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("RDD Action Aggregate") \
.master("local[*]") \
.getOrCreate()
sc = spark.sparkContext
Programmatic Accumulation:
# 1. Create a distributed RDD with 4 numbers split across 2 partitions
numbers_rdd = sc.parallelize([10, 20, 30, 40], numSlices=2)
print("Partition Layout:", numbers_rdd.glom().collect())
# Output: [[10, 20], [30, 40]]
# 2. Define seqOp: accumulates numbers locally inside each partition
# accum: a tuple (current sum, current count)
# value: the row element (integer)
def seq_op(accum, value):
new_sum = accum[0] + value
new_count = accum[1] + 1
return (new_sum, new_count)
# 3. Define combOp: merges accumulated tuples from separate partitions together
# accum1, accum2: local tuples from partition 1 and partition 2
def comb_op(accum1, accum2):
total_sum = accum1[0] + accum2[0]
total_count = accum1[1] + accum2[1]
return (total_sum, total_count)
# 4. Trigger the aggregate action
# Initial zero value is (sum=0, count=0)
final_sum, final_count = numbers_rdd.aggregate((0, 0), seq_op, comb_op)
# 5. Compute the final average
average = final_sum / final_count
print(f"Total Sum : {final_sum}") # 100
print(f"Total Count: {final_count}") # 4
print(f"Average : {average}") # 25.0